using System;
using System.Diagnostics;
using System.Text.RegularExpressions;
using System.Threading;
using System.Reflection;

namespace BassMati.Utilities
{
	/// <summary>
	/// Summary description for TraceExceptionFormatter.
	/// </summary>
	public class TraceFormatter
	{
		private TraceFormatter ( )
		{
			System.Configuration.AppSettingsReader configurationAppSettings = new System.Configuration.AppSettingsReader ( );
			string s = ((string)(configurationAppSettings.GetValue("Utilities.TraceFormatter.CategoryFormat", typeof(string))));;
			if ( s == "ShortFormat" ) CategoryFormat = shortFormat;
			else if ( s == "NormaFormat" ) CategoryFormat = normalFormat;
			else if ( s == "ThreadingFormat" ) CategoryFormat = threadingFormat;
			else if ( s == "ExtremeFormat" ) CategoryFormat = extremeFormat;
			else if ( s.Length > 0 ) CategoryFormat = s;
			else CategoryFormat = normalFormat;
		}

		/// <summary>Matches 3 blanks at the beginning of a line.</summary>
		protected static Regex stacktraceRegex = new Regex ( "^   ", RegexOptions.Multiline );
		
		/// <summary>Defines the line end sequence.</summary>
		protected const string eol = "\r\n";

		// Default formats for Category.
		protected static string extremeFormat = "{0} ({1})+({2}-{3})@{4:hh:mm.fff}";
		protected static string threadingFormat = "{0} (({2}-{3})";
		protected static string normalFormat = "{0}@{4:hh:mm.fff}";
		protected static string shortFormat = "{0}";

		// Accessor properties for the category format strings.
		public static string ExtremeFormat { get { return extremeFormat; }}
		public static string ThreadingFormat { get { return threadingFormat; }}
		public static string NormalFormat { get { return normalFormat; }}
		public static string ShortFormat { get { return shortFormat; }}
		
		/// <summary>Defines the appearance of the category field in the trace.</summary>
		public static string CategoryFormat = string.Empty;

		public static string FormatException ( System.Exception e )
		{
			System.Text.StringBuilder sb = new System.Text.StringBuilder ( );
			sb.Append ( e.Message );
			sb.Append ( eol );
			sb.Append ( stacktraceRegex.Replace( e.StackTrace, new string( ' ', Trace.IndentSize * (Trace.IndentLevel + 1))));
			return sb.ToString ();
		}

		public static string FormatExceptionShort ( System.Exception e )
		{
			System.Text.StringBuilder sb = new System.Text.StringBuilder ( );
			sb.Append ( e.Message );
			return sb.ToString ();
		}

		public static string FormatCategory( string category )
		{
			string assembyName = Assembly.GetExecutingAssembly().FullName;
			string threadName = Thread.CurrentThread.Name;
			int threadID = AppDomain.GetCurrentThreadId( );
			return string.Format( CategoryFormat, category, Thread.GetDomain().FriendlyName, threadID, threadName, System.DateTime.Now  );
		}
	}
}
